﻿/**	@file		invoke_cast.hpp
 *	@date		(2009-12-13 22:33:03)/(2011-05-15 21:45:04)
 *-----------------------------------------------------------------------------
 *	@version	1.0.6.9
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LOLIX__TOY__INVOKE_CAST__HPP__K_IN_G__)
#define		__LOLIX__TOY__INVOKE_CAST__HPP__K_IN_G__

#if			!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
	#include	"../lolix_macro.h"
#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)

#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

#if			!defined(__LOLIX__TOY__L_X_ASSERT_NICK__K_IN_G__)
	#include	"./lx_assert.h"
#endif	//	!defined(__LOLIX__TOY__L_X_ASSERT_NICK__K_IN_G__)


#if			!defined(__LOLIX__TOY__TYPE_LIST__H__PP__K_IN_G__)
	#include	"./type_list.hpp"
#endif	//	!defined(__LOLIX__TOY__TYPE_LIST__H__PP__K_IN_G__)

namespace lolix{namespace toy{
	template<typename _T_rtv, bool _V_is_const, typename _Tlist = type_list<void, void, void, void, void, void>, typename _T_val = void>
	class invoker_process;
	template<typename _T_rtv, bool _V_is_const, typename _Tlist = type_list<void, void, void, void, void, void>, typename _T_val = void>
	class invoker;
	namespace _help
	{
		template<typename _Tlist, typename _Tret, typename _Tval>
		struct _type_list_2_proc;

		template<typename _Tret, typename _Tval>
		struct _type_list_2_proc< type_list<void, void, void, void, void, void>, _Tret, _Tval >
		{
			typedef _Tret(LOLIX_CALL _Tval::*fn_proc)(void);
			typedef _Tret(LOLIX_CALL _Tval::*const_fn_proc)(void)const;
		};
	}

	template<typename _T_rtv, bool _T_is_const, typename _Tlist, typename _T_val>
	class invoker
	{
		typedef invoker<_T_rtv, _T_is_const, _Tlist, _T_val> this_type;
		typedef void (this_type::*t_fn_proc)(void);
		t_fn_proc _fn_proc;
	public:
		typedef	_Tlist	param_types;
		typedef typename _Tlist::template types<0>::type	param_type_0;
		typedef typename _Tlist::template types<1>::type	param_type_1;
		typedef typename _Tlist::template types<2>::type	param_type_2;
		typedef typename _Tlist::template types<3>::type	param_type_3;
		typedef typename _Tlist::template types<4>::type	param_type_4;
		typedef typename _Tlist::template types<5>::type	param_type_5;

		LOLIX_INLINE_CALL invoker(void)
			{
			}

		void LOLIX_INLINE_CALL swap(this_type& o)
			{
			lolix::swap(_fn_proc, o._fn_proc);
			}

		#pragma region	构造函数
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(void))
			{
			STATIC_ASSERT(_Tlist::size == 0);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(void)const)
			{
			STATIC_ASSERT(_Tlist::size == 0);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0))
			{
			STATIC_ASSERT(_Tlist::size == 1);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0)const)
			{
			STATIC_ASSERT(_Tlist::size == 1);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1))
			{
			STATIC_ASSERT(_Tlist::size == 2);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1)const)
			{
			STATIC_ASSERT(_Tlist::size == 2);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2))
			{
			STATIC_ASSERT(_Tlist::size == 3);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2)const)
			{
			STATIC_ASSERT(_Tlist::size == 3);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3))
			{
			STATIC_ASSERT(_Tlist::size == 4);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3)const)
			{
			STATIC_ASSERT(_Tlist::size == 4);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4))
			{
			STATIC_ASSERT(_Tlist::size == 5);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4)const)
			{
			STATIC_ASSERT(_Tlist::size == 5);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4, param_type_5 ))
			{
			STATIC_ASSERT(_Tlist::size == 6);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL invoker(_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4, param_type_5 )const)
			{
			STATIC_ASSERT(_Tlist::size == 6);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			}
		#pragma endregion


		#pragma region	赋值函数
		template<typename _Tx>
		this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(void))
			{
			STATIC_ASSERT(_Tlist::size == 0);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(void)const)
			{
			STATIC_ASSERT(_Tlist::size == 0);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0))
			{
			STATIC_ASSERT(_Tlist::size == 1);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0)const)
			{
			STATIC_ASSERT(_Tlist::size == 1);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1))
			{
			STATIC_ASSERT(_Tlist::size == 2);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1)const)
			{
			STATIC_ASSERT(_Tlist::size == 2);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2))
			{
			STATIC_ASSERT(_Tlist::size == 3);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2)const)
			{
			STATIC_ASSERT(_Tlist::size == 3);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3))
			{
			STATIC_ASSERT(_Tlist::size == 4);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3)const)
			{
			STATIC_ASSERT(_Tlist::size == 4);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4))
			{
			STATIC_ASSERT(_Tlist::size == 5);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4)const)
			{
			STATIC_ASSERT(_Tlist::size == 5);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4, param_type_5))
			{
			STATIC_ASSERT(_Tlist::size == 6);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			STATIC_ASSERT(!_T_is_const);
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL this_type& operator = (_T_rtv (LOLIX_CALL _Tx::*proc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4, param_type_5)const)
			{
			STATIC_ASSERT(_Tlist::size == 6);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, _Tx>::value == 1));
			STATIC_ASSERT(sizeof(proc) == sizeof(_fn_proc));
			_fn_proc = reinterpret_cast<t_fn_proc&>(proc);
			return *this;
			}
		#pragma endregion


		#pragma region	调用函数
		template<typename _Tx>
		LOLIX_INLINE_CALL _T_rtv ivk_by(_Tx* ptr)const
			{
			STATIC_ASSERT(_Tlist::size == 0);
			typedef _T_rtv (LOLIX_CALL this_type::*_T_FnProc)(void);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, typename remove_const<_Tx>::type>::value == 1));
			_T_FnProc fn_proc;
			reinterpret_cast<t_fn_proc&>(fn_proc) = reinterpret_cast<const t_fn_proc&>(_fn_proc);
			this_type* ptr_this = (this_type*)ptr;
			return (ptr_this->*fn_proc)();
			}

		template<typename _Tx>
		LOLIX_INLINE_CALL _T_rtv ivk_by(_Tx* ptr, param_type_0 p0)const
			{
			STATIC_ASSERT(_Tlist::size == 1);
			typedef _T_rtv (LOLIX_CALL this_type::*_T_FnProc)(param_type_0);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, typename remove_const<_Tx>::type>::value == 1));
			_T_FnProc fn_proc;
			reinterpret_cast<t_fn_proc&>(fn_proc) = reinterpret_cast<const t_fn_proc&>(_fn_proc);
			this_type* ptr_this = (this_type*)ptr;
			return (ptr_this->*fn_proc)(p0);
			}

		template<typename _Tx>
		LOLIX_INLINE_CALL _T_rtv ivk_by(_Tx* ptr, param_type_0 p0, param_type_1 p1)const
			{
			STATIC_ASSERT(_Tlist::size == 2);
			typedef _T_rtv (LOLIX_CALL this_type::*_T_FnProc)(param_type_0, param_type_1);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, typename remove_const<_Tx>::type>::value == 1));
			_T_FnProc fn_proc;
			reinterpret_cast<t_fn_proc&>(fn_proc) = reinterpret_cast<const t_fn_proc&>(_fn_proc);
			this_type* ptr_this = (this_type*)ptr;
			return (ptr_this->*fn_proc)(p0, p1);
			}

		template<typename _Tx>
		LOLIX_INLINE_CALL _T_rtv ivk_by(_Tx* ptr, param_type_0 p0, param_type_1 p1, param_type_2 p2)const
			{
			STATIC_ASSERT(_Tlist::size == 3);
			typedef _T_rtv (LOLIX_CALL this_type::*_T_FnProc)(param_type_0, param_type_1, param_type_2);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, typename remove_const<_Tx>::type>::value == 1));
			_T_FnProc fn_proc;
			reinterpret_cast<t_fn_proc&>(fn_proc) = reinterpret_cast<const t_fn_proc&>(_fn_proc);
			this_type* ptr_this = (this_type*)ptr;
			return (ptr_this->*fn_proc)(p0, p1, p2);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL _T_rtv ivk_by(_Tx* ptr, param_type_0 p0, param_type_1 p1, param_type_2 p2, param_type_3 p3)const
			{
			STATIC_ASSERT(_Tlist::size == 4);
			typedef _T_rtv (LOLIX_CALL this_type::*_T_FnProc)(param_type_0, param_type_1, param_type_2, param_type_3);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, typename remove_const<_Tx>::type>::value == 1));
			_T_FnProc fn_proc;
			reinterpret_cast<t_fn_proc&>(fn_proc) = reinterpret_cast<const t_fn_proc&>(_fn_proc);
			this_type* ptr_this = (this_type*)ptr;
			return (ptr_this->*fn_proc)(p0, p1, p2, p3);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL _T_rtv ivk_by(_Tx* ptr, param_type_0 p0, param_type_1 p1, param_type_2 p2, param_type_3 p3, param_type_4 p4)const
			{
			STATIC_ASSERT(_Tlist::size == 5);
			typedef _T_rtv (LOLIX_CALL this_type::*_T_FnProc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, typename remove_const<_Tx>::type>::value == 1));
			_T_FnProc fn_proc;
			reinterpret_cast<t_fn_proc&>(fn_proc) = reinterpret_cast<const t_fn_proc&>(_fn_proc);
			this_type* ptr_this = (this_type*)ptr;
			return (ptr_this->*fn_proc)(p0, p1, p2, p3, p4);
			}
		template<typename _Tx>
		LOLIX_INLINE_CALL _T_rtv ivk_by(_Tx* ptr, param_type_0 p0, param_type_1 p1, param_type_2 p2, param_type_3 p3, param_type_4 p4, param_type_5 p5)const
			{
			STATIC_ASSERT(_Tlist::size == 6);
			typedef _T_rtv (LOLIX_CALL this_type::*_T_FnProc)(param_type_0, param_type_1, param_type_2, param_type_3, param_type_4, param_type_5);
			STATIC_ASSERT((lolix::type::type_equal<_T_val, void>::value == 1 || lolix::type::type_equal<_T_val, typename remove_const<_Tx>::type>::value == 1));
			_T_FnProc fn_proc;
			reinterpret_cast<t_fn_proc&>(fn_proc) = reinterpret_cast<const t_fn_proc&>(_fn_proc);
			this_type* ptr_this = (this_type*)ptr;
			return (ptr_this->*fn_proc)(p0, p1, p2, p3, p4, p5);
			}
		#pragma endregion
	};

	template<typename _T_rtv, bool _T_is_const, typename _Tlist, typename _T_val>
	class invoker_process
	{
		typedef invoker_process<_T_rtv, _T_is_const, _Tlist, _T_val> this_type;
		typedef invoker<_T_rtv, _T_is_const, _Tlist, _T_val> invoke_type;
		typedef typename type::type_choise<_T_is_const, const void*, void*>::type _Tptr;
		invoke_type	_ivkr;
		_Tptr		_ptr;
		struct _no_used;
	public:
		typedef typename invoke_type::param_types	param_types;
		typedef typename invoke_type::param_type_0	param_type_0;
		typedef typename invoke_type::param_type_1	param_type_1;
		typedef typename invoke_type::param_type_2	param_type_2;
		typedef typename invoke_type::param_type_3	param_type_3;
		typedef typename invoke_type::param_type_4	param_type_4;
		typedef typename invoke_type::param_type_5	param_type_5;

		LOLIX_INLINE_CALL invoker_process(void)
			: _ptr(0)
			{
			}

		template<typename _Ty, typename _Tf>
		LOLIX_INLINE_CALL invoker_process(_Ty* ptr, _Tf proc)
			: _ivkr(proc)
			, _ptr(ptr)
			{
			}

		template<typename _Tf>
		this_type& operator = (_Tf proc)
			{
			_ivkr = proc;
			return *this;
			}

		template<typename _Ty>
		this_type& operator = (_Ty* ptr)
			{
			_ptr = ptr;
			return *this;
			}

		template<typename _Tcast>
		LOLIX_INLINE_CALL _Tcast cast_type(void)const
			{
			return static_cast<_Tcast>(_ptr);
			}

		LOLIX_INLINE_CALL operator _no_used*(void)const
			{ return (_no_used*)_ptr; }

		LOLIX_INLINE_CALL _T_rtv operator()(void)const
			{
			return _ivkr.ivk_by(_ptr);
			}
		LOLIX_INLINE_CALL _T_rtv operator()(param_type_0 p0)const
			{
			return _ivkr.ivk_by((const _T_val*)_ptr, p0);
			}
		LOLIX_INLINE_CALL _T_rtv operator()(param_type_0 p0, param_type_1 p1)const
			{
			return _ivkr.ivk_by((const _T_val*)_ptr, p0, p1);
			}
		LOLIX_INLINE_CALL _T_rtv operator()(param_type_0 p0, param_type_1 p1, param_type_2 p2)const
			{
			return _ivkr.ivk_by((const _T_val*)_ptr, p0, p1, p2);
			}
		LOLIX_INLINE_CALL _T_rtv operator()(param_type_0 p0, param_type_1 p1, param_type_2 p2, param_type_3 p3)const
			{
			return _ivkr.ivk_by((const _T_val*)_ptr, p0, p1, p2, p3);
			}
		LOLIX_INLINE_CALL _T_rtv operator()(param_type_0 p0, param_type_1 p1, param_type_2 p2, param_type_3 p3, param_type_4 p4)const
			{
			return _ivkr.ivk_by((const _T_val*)_ptr, p0, p1, p2, p3, p4);
			}
		LOLIX_INLINE_CALL _T_rtv operator()(param_type_0 p0, param_type_1 p1, param_type_2 p2, param_type_3 p3, param_type_4 p4, param_type_5 p5)const
			{
			return _ivkr.ivk_by((const _T_val*)_ptr, p0, p1, p2, p3, p4, p5);
			}

		void LOLIX_INLINE_CALL swap(this_type& o)
			{
			lolix::swap(_ptr, o._ptr);
			lolix::swap(_ivkr, o._ivkr);
			}
	};
}}

namespace lolix{
	template<typename _T_rtv, bool _T_is_const, typename _Tlist, typename _T_val>
	void LOLIX_INLINE_CALL swap(toy::invoker<_T_rtv, _T_is_const, _Tlist, _T_val>& l, toy::invoker<_T_rtv, _T_is_const, _Tlist, _T_val>& r)
		{
		l.swap(r);
		}

	template<typename _T_rtv, bool _T_is_const, typename _Tlist, typename _T_val>
	void LOLIX_INLINE_CALL swap(toy::invoker_process<_T_rtv, _T_is_const, _Tlist, _T_val>& l, toy::invoker_process<_T_rtv, _T_is_const, _Tlist, _T_val>& r)
		{
		l.swap(r);
		}
}
#endif	//	!defined(__LOLIX__TOY__INVOKE_CAST__HPP__K_IN_G__)
